//Transformations-based sprite class
#ifndef _HELPER_TRSPRITE_H_
#define _HELPER_TRSPRITE_H_

#include "graphics/graphics.h"
#include "math/vec2.h"
#include <string>
#include "sprite_set.h"

class Image;
class SpriteInstance;


//QUAD POINTS:
//
//[0]-------[1]
// |         |
// |         |
// |         |
// |         |
//[3]-------[2]


class TrSprite
{
public:

	//Constructor and destructor
	TrSprite();
	~TrSprite();


	//METHODS

	//main routines
	bool                     Render();
	bool                     Render_PerspCorByHeight(float MaxHeight);

	bool                     Tick(float dt);

	bool				     IsValid() const { return (m_pImage || m_pSpriteInstance); };

	//helper routines
	void                     SetupSprite(const std::string& ImageFile, bool IsAdditive = false, bool IsMipMapped = false,
										 bool IsVisible = true, bool QuickAlpha = false, COLOR Color = 0xFFFFFFFF,
										 const math::Vec2& UV1 = math::Vec2(0.0f,0.0f), const math::Vec2& UV2 = math::Vec2(1.0f,1.0f));

	//visibility routines
	void                     SetVisible(bool IsVisible = true) {m_IsVisible = IsVisible;};
	bool                     IsVisible() {return m_IsVisible;};


	//quad routines
	void                     Quad_Setup(const math::Vec2& TopLeft, const math::Vec2& Size);
	void                     Quad_Setup(const math::Vec2& P0, const math::Vec2& P1, const math::Vec2& P2, const math::Vec2& P3);
	void                     Quad_SetupCentered(const math::Vec2& Center, float Radius);
	void                     Quad_SetupCentered(const math::Vec2& Center, const math::Vec2& HorAndVerRadiuses);
	void                     Quad_SetupTLBR(const math::Vec2& TopLeft, const math::Vec2& BottomRight);
	void					 Quad_SetupFromImageTL(const math::Vec2& TopLeft);
	void					 Quad_SetupFromImageCentered(const math::Vec2& Center);

	void                     Quad_Move(const math::Vec2& Shift);
	void                     Quad_MoveX(float Shift);
	void                     Quad_MoveY(float Shift);
	
	void                     Quad_Rotate(const math::Vec2& Center, float Degrees);

	void                     Quad_Scale(const math::Vec2& Center, float ScaleFactor);

	math::Vec2               Quad_GetPoint(int I);


	//color routines
	void                     SetColor(COLOR Color = 0xFFFFFFFF);
	void                     SetColor(COLOR C0, COLOR C1, COLOR C2, COLOR C3);
	COLOR                    GetColor(int I);

	
	//texture coords routines
	void                     SetUV(const math::Vec2& UV1 = math::Vec2(0.0f, 0.0f), const math::Vec2& UV2 = math::Vec2(1.0f, 1.0f));
	void                     SetUV1(const math::Vec2& UV1);
	void                     SetUV2(const math::Vec2& UV2);
	const math::Vec2&	     GetUV1() const { return m_UV1; };
	const math::Vec2&	     GetUV2() const { return m_UV2; };

	
	//image routines
	void                     SetImage(const std::string& ImageFile);
	void					 SetImage(const char* ImageData, int DataSize);
	Image*				     GetImage() const { return m_pImage; };


	const math::Vec2&		 GetImageSize() {return m_ImageSize;};


	//additive routines
	void                     SetAdditive(bool IsAdditive) {m_IsAdditive = IsAdditive;};
	bool                     GetAdditive() {return m_IsAdditive;};

	//mipmapped routines
	void					 SetMipMapped(bool IsMipMapped) {m_IsMipMapped = IsMipMapped;};
	bool					 GetMipMapped() {return m_IsMipMapped;};


	//quick alpha routines
	void					 SetQuickAlpha(bool QuickAlpha) {m_QuickAlpha = QuickAlpha;};
	bool					 GetQuickAlpha() {return m_QuickAlpha;};


	//sprite instance related
	//ui::SpriteInstance*		 GetSpriteInst() const { return m_pSpriteInstance; };
	bool				     UpdateTime(float& Time, float dt) { if (m_pSpriteInstance) return m_pSpriteInstance->UpdateTime(m_LoopCount,Time, dt, m_Looped); return true; };
	void				     ForceAnimTime(float Time) { m_Timer  = Time; };
	float				     GetTimer() const { return m_Timer; };
	const std::string&	     GetFilename() const { return m_Filename; };
	void				     SetPause(bool Paused) { m_Paused = Paused; }
	bool					 GetPause() const { return m_Paused; }
	void					 SetLoop(bool Loop) { m_Looped = Loop; }
	bool					 GetLoop() const		{ return m_Looped; }
	void					 SetLoopCount(int NewCount)		{ m_LoopCount = NewCount; }
	int						 GetLoopCount() const	{ return m_LoopCount; }
	float					 GetTotalAnimTime()	const;
	void					 SetAnimTime(float Time) {m_Timer = Time;};
	void					 SetAnimTimeNormalized(float Time) {m_Timer = Time * GetTotalAnimTime();};
	float					 GetAnimTime() const {return m_Timer;};
	float					 GetAnimTimeNormalized() const {return m_Timer/GetTotalAnimTime();};

	//localization
	void					 UpdateLocalization();

	//MEMBERS


protected:

	//METHODS

	//invalidation
	void                     Invalidate();


	//MEMBERS
	
	//visibility state
	bool                    m_IsVisible;

	//the quad
	math::Vec2              m_Quad[4];

	//texture coords
	math::Vec2				m_UV1, m_UV2;

	//color values
	COLOR                   m_Color[4];

	//image pointer
	Image*                  m_pImage;

	//image size
	math::Vec2				m_ImageSize;

	//additive
	bool                    m_IsAdditive;

	//mipmapped
	bool					m_IsMipMapped;

	//quick alpha render
	bool					m_QuickAlpha;

	//SpriteInstance-related
	ui::SpriteInstance*		m_pSpriteInstance;
	float					m_Timer;
	bool					m_Paused;
	bool					m_Looped;
	int						m_LoopCount;

	bool					m_IsLocalized;
	std::string				m_Filename;

};//class TrSprite





















#endif